package gu.sql2java.wherehelper;

import static com.google.common.base.Preconditions.checkArgument;

import java.lang.reflect.Method;
import java.lang.reflect.Parameter;
import java.util.Map;

import com.google.common.base.CaseFormat;
import com.google.common.base.Function;
import com.google.common.collect.Maps;

import gu.sql2java.wherehelper.annotations.EnableWhereHelper;

public class WhereHelpers {
	private WhereHelpers(){
		
	}

	/**
	 * @param name
	 * @return 将变量名转为蛇形命名法格式的字符串
	 */
	public static String toSnakecase(String name){
		return null == name ? name : CaseFormat.LOWER_CAMEL.to(CaseFormat.LOWER_UNDERSCORE,name);
	}

	/**
	 * @param name
	 * @return 将变量名转为驼峰命名法格式的字符串
	 */
	public static String toCamelcase(String name){
		return null == name ? name : CaseFormat.LOWER_UNDERSCORE.to(CaseFormat.LOWER_CAMEL, name);
	}
	/**
	 * 判断 变量是否为驼峰命名法格式的字符串
	 * @param name
	 */
	public static boolean isCamelcase(String name){
		return null == name ? false :  name.equals(toCamelcase(name)) ;
	}
	/**
	 * 判断 变量是否为驼峰命名法格式的字符串
	 * @param name
	 */
	public static boolean isSnakelcase(String name){
		return null == name ? false :  name.equals(toSnakecase(name)) ;
	}
	/**
	 * 从服务方法注解中读取参数创建WhereHelper<br>
	 * 如果没有找到注解{@link EnableWhereHelper}或{@link EnableWhereHelper#enable()}为{@code false},
	 * 则返回 {@code null}
	 * @param method 服务方法,为{@code null}返回{@code null}
	 * @param args 服务方法参数数组,长度必须与服务方法定义的参数个数相等,否则抛出异常
	 * @param valueSupplier 根据变量名获取变量值的实例,为{@code null}忽略,
	 *                                       用于获取方法输入参数之外定义的参数,比如HTTP Request,为{@code null}忽略
	 * @return WhereHelper 实例, 或{@code null}
	 */
	public static WhereHelper buildWhereHelperIfEnable(Method method, Object[] args, Function<String,String>valueSupplier){
		if(null != method){
			EnableWhereHelper enableWhereHelper = method.getAnnotation(EnableWhereHelper.class);
			if(null != enableWhereHelper && enableWhereHelper.enable()){
				/** 根据方法参数创建参数名-参数值映射 */
				Map<String, Object> m = Maps.newHashMap();
				Parameter[] params = method.getParameters();
				if(params.length > 0){
					/**
					 * 根据输入参数args不为null且长度与方法定义的参数个数相等
					 */
					checkArgument(null != args && params.length == args.length,"args must not be null and length == %s",params.length);
					for(int i = 0;i<params.length; ++i){
						m.put(params[i].getName(), args[i]);
					}
				}
				return WhereHelper.builder()
						/**  从服务方法注解中创建表达式*/
						.from(method.getAnnotations())
						/** 在PageHelper Spring AOP场景下使用时，使用前端提供的分页参数,所以强制为false */
						.pagequery(false)
						.build()
						/**
						 * 将从服务方法的参数注入WhereHelper
						 */
						.with(m)
						/**
						 * 将从服务HTTP请求(GET)中获取的参数注入WhereHelper,
						 * 如果服务方法参数和GET参数中有共同的参数则以GET参数优先
						 */
						.with(valueSupplier);
			}
		}
    	return null;
	}
}
